package com.zhangdy.agent.core;//package com.zhangdy.agent.core;

import java.lang.instrument.Instrumentation;
import java.util.Arrays;

public class ZhangdyAgentMain {

    private static final String CLASS_LOADER = "org.springframework.boot.loader.LaunchedURLClassLoader";
    private static final String SWAP_CLIENT = "com.zhangdy.agent.common.utils.HotSwapClient";
    private static final String SWAP_CLIENT_SETTER = "setInstrumentation";

    public static Instrumentation instrumentation;
    public static ClassLoader classLoader;

    public static void premain(String args, Instrumentation inst) throws Throwable {

    }

    public static void agentmain(String args, Instrumentation inst) throws Throwable {
        System.out.println("-------------------- agentmain start --------------------");
        instrumentation = inst;
        // 获得程序类加载器 LaunchedURLClassLoader
        classLoader = getClassLoader(inst);
        // 获得 LaunchedURLClassLoader 类加载器中的  类实例
        Class<?> clientClass = classLoader.loadClass(SWAP_CLIENT);
        // 经过反射方式设置 Instrumentation
        clientClass.getMethod(SWAP_CLIENT_SETTER, Instrumentation.class).invoke(null, inst);

        inst.addTransformer(
                (loader, className, classBeingRedefined,
                 protectionDomain, classfileBuffer) -> classfileBuffer
        );
        System.out.println("-------------------- agentmain end   --------------------");

    }
    private static ClassLoader getClassLoader(Instrumentation inst) {
        // 获取全部已加载的类
        Class[] loadedClasses = inst.getAllLoadedClasses();
        // 找出 LaunchedURLClassLoader
        return Arrays.stream(loadedClasses)
                .filter(c -> c.getClassLoader() != null && c.getClassLoader().getClass() != null)
                .filter(c -> CLASS_LOADER.equals(c.getClassLoader().getClass().getName()))
                .map(Class::getClassLoader)
                .findFirst()
                .orElse(Thread.currentThread().getContextClassLoader());
    }

}
